/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.order.controller.admin;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rzico.account.entity.Receivable;
import com.rzico.account.entity.Refunds;
import com.rzico.account.model.Attach;
import com.rzico.account.service.PaymentService;
import com.rzico.account.service.ReceivableService;
import com.rzico.annotation.Log;
import com.rzico.base.BaseController;
import com.rzico.base.CommResult;
import com.rzico.basics.entity.*;
import com.rzico.basics.service.*;
import com.rzico.core.entity.*;
import com.rzico.core.service.*;
import com.rzico.entity.PageResult;
import com.rzico.entity.Pageable;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.AskforStatusEnum;
import com.rzico.order.enumx.OrderShippingStatusEnum;
import com.rzico.order.enumx.OrderStatusEnum;
import com.rzico.order.enumx.ShippingStatusEnum;
import com.rzico.order.service.*;
import com.rzico.util.HttpUtils;
import com.rzico.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.jasperreports.engine.JRException;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 销售单控制层
 *
 * @author Rzico Boot
 * @version 1.0
 * @date 2020-02-17
 */
@Api(description = "销售单接口")
@RestController
@RequestMapping("/admin/order")
public class OrderAdminController extends BaseController {

    @Value("${rzico.filePath.windows}")
    private String windowsFilePath;

    @Value("${rzico.filePath.linux}")
    private String linuxFilePath;

    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private SysSequenceService sysSequenceService;

    @Autowired
    private SysOfficeService sysOfficeService;

    @Autowired
    protected SysEmployeeService sysEmployeeService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private AskforService askforService;

    @Autowired
    private ProductService productService;

    @Autowired
    private ReceiverService receiverService;

    @Autowired
    private SysReportService sysReportService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private OrderLogService orderLogService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private OrderPlanService orderPlanService;

    @Autowired
    private BomItemService bomItemService;

    @Autowired
    private CouponCodeService couponCodeService;

    @Autowired
    private ShippingService shippingService;

    @Autowired
    private ReceivableService receivableService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private ChefService chefService;

    /**
     * 分页查询销售单
     *
     * @return
    */
    @ApiOperation("分页查询销售单")
    @GetMapping("/list")
    @ApiImplicitParams({@ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String", paramType = "query") ,
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "orderType", value = "订单类型（0.即配订单,2.预约订单）", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "memberId", value = "客户Id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "companyId", value = "所属企业", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "orderSn", value = "订单号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "productId", value = "商品ID", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "收货电话", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "orderStatus", value = "订单状态", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "paymentStatus", value = "付款状态", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "shippingStatus", value = "配送状态", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "keyword", value = "收货地址", dataType = "Integer", paramType = "query")
    })
    public CommResult<Order> list(Date startDate, Date endDate, Integer orderStatus,
                                  Integer paymentStatus,Long companyId,Integer orderType,String keyword, Integer shippingStatus,Long memberId,Long productId,String orderSn,String phone, Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);
        if (startDate!=null){
            params.put("startDate",DateUtils.truncate(startDate, Calendar.DATE));
        }
        if (endDate!=null){
            params.put("endDate", DateUtils.addMilliseconds(DateUtils.addDays(endDate,1),-1));
        }
        if (null != orderStatus){
            if (orderStatus==2) {
                params.put("compeleted", true);
            } else {
                params.put("orderStatus", orderStatus);
            }
        }
        if (null != orderType){
            params.put("orderType", orderType);
        }
        if (null != keyword){
            params.put("keyword", keyword);
        }
        if (null != paymentStatus){
            params.put("paymentStatus", paymentStatus);
        }
        if (null != shippingStatus){
            params.put("shippingStatus", shippingStatus);
        }
        if (null != memberId){
            params.put("memberId", memberId);
        } else {
            Enterprise enterprise = enterpriseService.getCurrent();
            SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
            if (!sysMch.getMchType().equals(0))  {
                params.put("enterpriseId", enterprise.getId());
            }

        }
        if (null != companyId){
            params.put("companyId", companyId);
        }
        if (null != orderSn){
            params.put("sn", orderSn);
        }
        if (null != productId){
            Product product = productService.findById(productId);
            params.put("goodsId", product.getGoodsId());
        }
        if (null != phone){
            params.put("phone", phone);
        }

        params.put("deleted", false);

        Page<Object> startPage = PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<Order> list = orderService.selectList(params);
        for (Order order:list) {
            if (order.getPaymentStatus().equals(2) || order.getShippingStatus().equals(2)) {
                Map<String,Object> askforParams = new HashMap<>();
                askforParams.put("orderId",order.getId());
                askforParams.put("askforing",true);

                List<Askfor> askforList = askforService.selectList(askforParams);
                if (askforList.size()>0) {
                    order.setAskfor(askforList.get(0));
                }

            }
        }
        PageResult<Order> pageResult = new PageResult<Order>(list, startPage.getTotal(), pageable);
        return CommResult.success(pageResult);
    }



    /**
     * 查询会员最后一个订单
     *
     * @return
     */
    @ApiOperation("查询会员最后一个订单")
    @GetMapping("/last")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "客户Id", dataType = "Long", paramType = "query")
    })
    public CommResult<Order> last(Long memberId, Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);

        if (null != memberId){
            params.put("memberId", memberId);
        } else {

            Enterprise enterprise = enterpriseService.getCurrent();
            SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());
            if (!sysMch.getMchType().equals(0))  {
                params.put("enterpriseId", enterprise.getId());
            }

        }

        params.put("shippingStatus", 1);
        params.put("paymentStatus", 1);
        params.put("deleted", false);

        Page<Object> startPage = PageHelper.startPage(1, 20);
        List<Order> list = orderService.selectList(params);

        Order order = null;

        for (Order o:list) {
            for (OrderItem orderItem:o.getItemList()) {
                if (orderItem.getSubType().equals(0) || orderItem.getSubType().equals(4)) {
                    order = o;
                    break;
                }
            }
        }
        return CommResult.success(order);
    }

    /**
     * 统计末完成订单数
     *
     * @return
     */
    @ApiOperation("统计末完成订单数")
    @PostMapping("/summary")
    public CommResult<Order> summary() {

        Enterprise enterprise = enterpriseService.getCurrent();
        SysMch sysMch = sysMchService.selectByPrimaryKey(enterprise.getMchId());

        Map<String,Object> data = new HashMap<>();
        Map<String,Object> params = new HashMap<>();

        //非管理员都启用数据权限
//        SysUser sysUser = sysUserService.getCurrent();
//        if (!sysUserService.isAdmin(sysUser)) {
//            params.put("dataScopeId",sysUser.getId());
//        }

        params.put("orderStatus",0);
        params.put("paymentStatus",0);
        params.put("shippingStatus",0);
        if (!sysMch.getMchType().equals(0))  {
            params.put("enterpriseId",enterprise.getId());
        }
        params.put("deleted",false);
        data.put("unpaid",orderService.selectRowCount(params));

        params.clear();
//        if (!sysUserService.isAdmin(sysUser)) {
//            params.put("dataScopeId",sysUser.getId());
//        }

        params.put("orderStatus",1);
        params.put("shippingStatus",0);
        params.put("paymentStatus",1);
        if (!sysMch.getMchType().equals(0))  {
            params.put("enterpriseId",enterprise.getId());
        }
        params.put("deleted",false);
        data.put("unshipping",orderService.selectRowCount(params));

        params.clear();
//        if (!sysUserService.isAdmin(sysUser)) {
//            params.put("dataScopeId",sysUser.getId());
//        }

        params.put("orderStatus",1);
        params.put("shippingStatus",1);
        params.put("paymentStatus",1);
        if (!sysMch.getMchType().equals(0))  {
            params.put("enterpriseId",enterprise.getId());
        }
        params.put("deleted",false);
        data.put("shipped",orderService.selectRowCount(params));


        return CommResult.success(data);

    }


    /**
     * 查询单条销售单
     *
     * @return
    */
    @ApiOperation("查询单条销售单")
    @GetMapping("/find/{id}")
    public CommResult<Order> find(@PathVariable Long id) {
        Order result = orderService.findById(id);

        if (result.getPaymentStatus().equals(2) || result.getShippingStatus().equals(2)) {
            Map<String,Object> askforParams = new HashMap<>();
            askforParams.put("orderId",result.getId());
            askforParams.put("askforing",true);

            List<Askfor> askforList = askforService.selectList(askforParams);
            if (askforList.size()>0) {
                result.setAskfor(askforList.get(0));
            }

        }


        Map<String,Object> data = new HashMap<>();
        data.put("order",result);

        if (result.getOfficeId()!=null && !"".equals(result.getOfficeId())) {
            SysOffice sysOffice = sysOfficeService.selectByPrimaryKey(result.getOfficeId());
            if (sysOffice!=null) {
                data.put("officeName", sysOffice.getName());
            } else {
                data.put("officeName", "无");
            }
        } else {
            data.put("officeName", "无");
        }
        if (result.getOperatorId()!=null && !"".equals(result.getOperatorId())) {
            SysEmployee sysUser = sysEmployeeService.selectByPrimaryKey(result.getOperatorId());
            if (sysUser!=null) {
                data.put("operatorName", sysUser.getName());
            } else {
                data.put("operatorName", "无");
            }
        } else {
            data.put("operatorName", "无");
        }

        if (result.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(result.getMemberId());
            data.put("memberName", member.getName());
            data.put("memberMemo", member.getMemo());
        }

        data.put("order",result);

        result.setItemList(orderItemService.getItemList(result.getId()));

        data.put("bomType",orderService.checkBomType(result));

        if (result.getPromoterId1()!=null) {
            Member member = memberService.selectByPrimaryKey(result.getPromoterId1());
            if (member!=null) {
                data.put("promoter1Name", member.getName());
            }
        }

        if (result.getPromoterId2()!=null) {
            Member member = memberService.selectByPrimaryKey(result.getPromoterId2());
            if (member!=null) {
                data.put("promoter2Name", member.getName());
            }
        }


        Map<String,Object> paymentParams = new HashMap<>();
        paymentParams.put("orderType",0);
        paymentParams.put("orderId",id);
        paymentParams.put("showed", 1);
        data.put("payments",paymentService.selectList(paymentParams));

        Map<String,Object> prms = new HashMap<>();
        prms.put("orderId",id);
        prms.put("sortField","id");
        prms.put("sortType","desc");
        data.put("orderLog",orderLogService.selectList(prms));

        List<OrderPlan> orderPlanList = orderPlanService.getItemList(result.getEnterpriseId(),result.getId(),null);
        for (OrderPlan orderPlan:orderPlanList) {
            orderPlan.setItemList(bomItemService.getItemList(orderPlan.getBomId(),String.valueOf(orderPlan.getSeqno())));
        }

        data.put("orderPlans",orderPlanList);

        paymentParams.clear();
        paymentParams.put("memberId", 0);
        paymentParams.put("status", 1);
        List<Receivable> receivableList = receivableService.selectList(paymentParams);
        BigDecimal receivableQuantity = BigDecimal.ZERO;
        BigDecimal receivableAmount = BigDecimal.ZERO;
        for (Receivable receivable:receivableList) {
            receivableAmount = receivableAmount.add(receivable.getAvailableAmount());
            receivableQuantity = receivableQuantity.add(receivable.calcAvailableQuantity());
        }

        data.put("receivableQuantity",0);
        data.put("receivableAmount", receivableAmount);


        if (result.getShopId()!=null) {
            Shop shop = shopService.selectByPrimaryKey(result.getShopId());
            if (shop!=null) {
                data.put("shopName",shop.getName());
                data.put("telephone",shop.getTelephone());

            }
        }


        if (result.getChefId()!=null) {
            Chef chef = chefService.selectByPrimaryKey(result.getChefId());
            data.put("chefName",chef.getName());
        }

        return CommResult.success(data);

    }

    /**
     * 保存销售单
     *
     * @param order
     * @return
     */
    @ApiOperation("保存销售单")
    @PostMapping("/save")
    public CommResult<Order> save(@RequestBody Order order) {
        logger.info(">>>>>>>>>>>>>>>>保存订单 start <<<<<<<<<<<<<<<<<");
        logger.info("保存订单参数：[{}]", order.toString());
        Assert.notNull(order, "订单参数为空");

        order.setSn(sysSequenceService.generate("order"));
        //计算相关费用及活动
        order = orderService.calculate(order);
        int affectCount = orderService.insertOrder(order);
        if (affectCount <= 0) {
            return CommResult.error();
        }
        Order result = orderService.findById(order.getId());
        logger.info(">>>>>>>>>>>>>>>>保存订单 end <<<<<<<<<<<<<<<<<");
        return CommResult.success(result);

    }

    /**
     * 批量删除销售单
     *
     * @param ids
     * @return
     */
    @Log(desc = "批量删除销售单", type = Log.LOG_TYPE.DEL)
    @ApiOperation("批量删除销售单,ids用逗号拼接")
    @PostMapping("/del/{ids}")
    public CommResult<Order> del(@PathVariable String ids) {
        try {
            orderService.deleteByIds(ids.split(","));
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }

        return CommResult.success();
    }

    /**
     * 订单编辑
     *
     * @param order
     * @return
     */
    @ApiOperation("订单编辑")
    @PostMapping("/update")
    public CommResult<Order> update(@RequestBody Order order) {
        logger.info(">>>>>>>>>>>>>>>>订单编辑 start <<<<<<<<<<<<<<<<<");
        logger.info("保存订单参数：[{}]", order.toString());
        Assert.notNull(order, "订单参数为空");
        Assert.notNull(order.getId(), "订单编码为空");
        Assert.notNull(order.getItemList(), "订单明细为空");
        Assert.notNull(order.getAmountPayable(), "订单应付金额为空");
        Assert.notNull(order.getSubPrice(), "商品汇总金额为空");
        Assert.notNull(order.getSubQuantity(), "商品汇总数量为空");

        int affectCount = orderService.update(order);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Order result = orderService.findById(order.getId());
        logger.info(">>>>>>>>>>>>>>>>订单编辑 end <<<<<<<<<<<<<<<<<");
        return CommResult.success(result);
    }

    /**
     * 订单确认
     *
     * @param id
     * @return
     */
    @ApiOperation("订单确认")
    @PostMapping("/confirm/{id}")
    public CommResult<Order> confirm(@PathVariable Long id,Long shopId,String shippingEmployeeId) {

        Assert.notNull(id, "订单编码为空");
        SysEmployee sysEmployee = sysEmployeeService.getCurrent();
        Order order = orderService.selectByPrimaryKey(id);
        if (order.getOrderMethod().equals(0)) {
            return CommResult.error("线上订单不能人工确认");
        }
        if (!order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId())) {
            return CommResult.error("不能重复确认");
        }
        int affectCount = orderService.confirm(id,sysEmployee);
        if (affectCount <= 0){
            return CommResult.error();
        }

        Order result = orderService.findById(id);
        return CommResult.success(result);

    }

    /**
     * 订单接单
     *
     * @param id
     * @return
     */
    @ApiOperation("订单接单")
    @PostMapping("/shipping/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "shopId", value = "发货仓库", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "orderDate", value = "发货日期", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "deliveryMethod", value = "接单方式(1.店家自送,2.骑手配送)", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "weekTime", value = "配送频次", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "shippingEmployeeId", value = "送货员", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "receiverId", value = "收货地址(不修改不传)", dataType = "Long", paramType = "query")
    })
    public CommResult<Order> shipping(@PathVariable Long id, Long shopId,String shippingEmployeeId, Date orderDate,String weekTime,Long receiverId, @RequestBody List<OrderItem> itemList) {

        Order order = orderService.selectByPrimaryKey(id);

        if (shopId==null) {
            return CommResult.error("发货仓库不能为空");
        }
        if (orderDate==null) {
            return CommResult.error("发货日期不能为空");
        }

        if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_UNCONFIRM.getId())) {
            return CommResult.error("订单未确认");
        }

        //检查退货状态
        Map<String,Object> params = new HashMap<>();
        params.put("orderId",id);
        params.put("askforing",true);

        Integer w = askforService.selectRowCount(params);
        if (w>0) {
            return CommResult.error("订单在退货中");
        }

        if (receiverId!=null) {
            Receiver receiver = receiverService.findById(receiverId);
            if (receiver!=null) {
                order.setReceiverId(receiver.getId());
                order.setAreaId(receiver.getAreaId());
                order.setAreaName(receiver.getAreaName());
                order.setAddress(receiver.getAddress());
                order.setConsignee(receiver.getConsignee());
                order.setPhone(receiver.getPhone());
                order.setLng(receiver.getLng());
                order.setLat(receiver.getLat());
                orderService.updateByPrimaryKeySelective(order);
            }
        }

/*
        Order order = orderService.selectByPrimaryKey(id);
        for (OrderItem orderItem:itemList) {
            if (orderItem.getSubType().equals(1)) {
                //检查是否存在待配送订单
                params.clear();
                params.put("status", 0);
                params.put("enterpriseId", order.getEnterpriseId());
                params.put("productId", orderItem.getProductId());
                params.put("planBeginDate", orderDate);
                w = orderPlanService.selectRowCount(params);
                if (w > 0) {
                    throw new CustomException("发货时间内存在待配送的套餐");
                }
            }
        }
*/

        if (itemList==null) {
            itemList = new ArrayList<>();
        }

        if (itemList.size()==0) {
            BigDecimal quantity = BigDecimal.ZERO;
            List<OrderItem> orderItemList = orderItemService.getItemList(id);
            for (OrderItem orderItem:orderItemList) {
                orderItem.setShippedQuantity(orderItem.getQuantity().subtract(orderItem.getReturnQuantity()).subtract(orderItem.getShippedQuantity()));
                quantity = quantity.add(orderItem.getShippedQuantity());
                itemList.add(orderItem);
            }
            if (quantity.compareTo(BigDecimal.ZERO)<=0) {
                return CommResult.error("没有待发商品");
            }
        }

        try {
            Warehouse warehouse = orderService.shipping(id, shopId, orderDate, weekTime, itemList, sysSequenceService.generate("warehouse"));

            //人工报单时，自动发货

            if (shippingEmployeeId!=null && !"".equals(shippingEmployeeId)) {
                Shipping shipping = new Shipping();
                shipping.setWarehouseId(warehouse.getId());
                shipping.setEnterpriseId(warehouse.getEnterpriseId());
                List<Shipping> shippingList = shippingService.select(shipping);
                for (Shipping shipping1:shippingList) {
                    shippingService.dispatch(shipping1.getId(), shopId, shippingEmployeeId);
                }
            }

        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }

        Order result = orderService.findById(id);
        return CommResult.success(result);

    }


    /**
     * 计算订单金额
     *
     * @param order
     * @return
     */
    @ApiOperation("计算订单金额")
    @PostMapping("/calculate")
    public CommResult<Order> calculate(@RequestBody Order order) {




        Order result = orderService.calculate(order);
        order.setPaymentVo(orderService.calculatePayment(order));

        Map<String,Object> data = new HashMap<>();
        data.put("order",result);
        data.put("shippingMethods",orderService.getShippingMethods(order));
        data.put("amount",order.getAmountPayable().subtract(order.calculatePaymentPaid()));

        if (result.getCouponCodeId()!=null) {
            CouponCode couponCode = couponCodeService.findById(result.getCouponCodeId());
            if (couponCode!=null) {
                data.put("couponCodeName",couponCode.getCoupon().getName());
            }
        }

        data.put("bomType",orderService.checkBomType(result));


        return CommResult.success(data);
    }


    /**
     * 打印
     *
     * @param orderId
     * @return
     */
    @ApiOperation("打印")
    @PostMapping("/print")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单ID", dataType = "String", paramType = "query")
    })
    public CommResult<Order> print(Long orderId) {

        try {
            orderService.print(orderId);
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }
        return CommResult.success();

    }

    /**
     * 报停/恢复
     *
     * @param orderId
     * @return
     */
    @ApiOperation("报停/恢复+")
    @PostMapping("/pause")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单ID", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "beginDate", value = "开始时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String", paramType = "query")
    })
    public CommResult<Order> pause(Long orderId,Date beginDate,Date endDate) {

        Order result = orderService.selectByPrimaryKey(orderId);
        orderPlanService.calculate(result,beginDate,endDate);
        return CommResult.success(orderPlanService.getItemList(result.getEnterpriseId(),result.getId(),null));

    }


    /**
     * 修改送货时间及收货地址
     *
     * @param orderId
     * @return
     */
    @ApiOperation("修改送货时间及收货地址")
    @PostMapping("/updateWeekAndReceiver")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单ID", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "weekTime", value = "配送周期", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "receiverId", value = "收货地址", dataType = "Long", paramType = "query")
    })
    public CommResult<Order> updateWeekAndReceiver(Long orderId,String weekTime,Long receiverId) {
        Order result = orderService.selectByPrimaryKey(orderId);

        if (weekTime!=null) {
            result.setWeekTime(weekTime);
        }
        if (receiverId!=null) {
            result.setReceiverId(receiverId);
            Receiver receiver = receiverService.findById(receiverId);
            result.setAreaId(receiver.getAreaId());
            result.setAreaName(receiver.getAreaName());
            result.setAddress(receiver.getAddress());
            result.setConsignee(receiver.getConsignee());
            result.setPhone(receiver.getPhone());
            result.setLng(receiver.getLng());
            result.setLat(receiver.getLat());
        }

        orderService.updateByPrimaryKeySelective(result);
        if (weekTime!=null) {
            orderPlanService.calculate(result, null, null);
        }

        return CommResult.success(orderPlanService.getItemList(result.getEnterpriseId(),result.getId(),null));

    }

    /**
     * 计算预计送达时间
     *
     * @param week
     * @return
     */
    @ApiOperation("计算预计送达时间")
    @PostMapping("/calculateEstimateDate")
    public CommResult<Order> calculateEstimateDate(String week) {

        Enterprise enterprise = enterpriseService.getCurrent();
        Map<String,Object> data = new HashMap<>();
        data.put("estimateDate",enterpriseService.calcEstimateDate(enterprise.getId(),new Date(),week));
        return CommResult.success(data);

    }


    /**
     * 获取用户最近3次的购买记录
     *
     * @param memberId productId
     * @return
     */
    @ApiOperation("获取用户最近3次的购买记录")
    @PostMapping("/getHistoryList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "客户ID", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "productId", value = "商品ID", dataType = "String", paramType = "query")
    })
    public CommResult<OrderItem> getHistoryList(Long memberId,Long productId) {

        Map<String,Object> params = new HashMap<>();
        params.put("memberId",memberId);
        params.put("productId",productId);
        params.put("sortField","create_date");
        params.put("sortType","desc");

        Page<Object> startPage = PageHelper.startPage(1,2);
        List<OrderItem> list = orderItemService.selectList(params);
        return CommResult.success(list);

    }

    /**
     * 发起退货
     *
     * @param id
     * @return
     */

    @ApiOperation("发起退货")
    @PostMapping("/returns/{id}")

//  @ApiImplicitParams({@ApiImplicitParam(name = "shopId", value = "退货仓库", dataType = "String", paramType = "query"),
//      @ApiImplicitParam(name = "orderDate", value = "发货日期", dataType = "String", paramType = "query")
//  })

    public CommResult<Order> returns(@PathVariable Long id,Long shopId, Date orderDate, @RequestBody List<OrderItem> itemList) {


        Order order = orderService.selectByPrimaryKey(id);

        if (order.getGiftCardId()!=null) {
            return CommResult.error("礼卡订单不能退");
        }
        if (order.getGroupBuyId()!=null) {
            return CommResult.error("团购订单不能退");
        }

        //检查退货状态
        Map<String,Object> params = new HashMap<>();
        params.put("orderId",id);
        params.put("askforing",true);

        Integer w = askforService.selectRowCount(params);
        if (w>0) {
            return CommResult.error("不能重复退款");
        }

        Askfor askfor = null;
        try {
            askfor = askforService.askfor(id, itemList, sysSequenceService.generate("askfor"), "", "商户发起退货");
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }

        //检查是否符合极速退款条件,商家发起退款，默认自动
        try {

            askforService.confirm(askfor.getId());

            //不能自动打款，只能自动同意
//            List<Refunds> refundsList = askforService.refund(askfor.getId(), sysSequenceService.generate("refunds"));
//            for (Refunds refunds:refundsList) {
//                //TODO发送退款通知
//                Attach attachQueue = new Attach();
//                attachQueue.setCode("0000");
//                attachQueue.setId(String.valueOf(refunds.getId()));
//                attachQueue.setQueue("queue.refunds.submit");
//                Message message = MessageBuilder
//                        .withBody(JSON.toJSONString(attachQueue).getBytes())
//                        .setContentType(MessageProperties.CONTENT_TYPE_JSON)
//                        .build();
//                CorrelationData correlationData = new CorrelationData();
//                correlationData.setId(UUID.randomUUID().toString());
//                logger.info("发送 MQ");
//                rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);
//
//            }

        } catch (Exception e) {
            logger.error(e.getMessage());
            return CommResult.error(e.getMessage());
        }

//        askfor = askforService.findById(askfor.getId());
//        return CommResult.success(askfor);
//
//        if (shopId==null) {
//            return CommResult.error("退货仓库不能为空");
//        }
//        if (orderDate==null) {
//            return CommResult.error("退货日期不能为空");
//        }
//        orderService.returns(id, shopId ,orderDate,itemList,sysSequenceService.generate("warehouse"));

        Order result = orderService.findById(id);
        return CommResult.success(result);

    }


    /**
     * 退货保存并
     *
     * @param id
     * @return
     */
//    @ApiOperation("退货保存")
//    @PostMapping("/returnsAndAudit/{id}")
//    @ApiImplicitParams({@ApiImplicitParam(name = "shopId", value = "退货仓库", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "orderDate", value = "发货日期", dataType = "String", paramType = "query")
//    })
//    public CommResult<Order> returnsAndAudit(@PathVariable Long id,Long shopId, Date orderDate, @RequestBody List<OrderItem> itemList) {
//        if (shopId==null) {
//            return CommResult.error("退货仓库不能为空");
//        }
//        if (orderDate==null) {
//            return CommResult.error("退货日期不能为空");
//        }
//        orderService.returnsAndAudit(id, shopId ,orderDate,itemList,sysSequenceService.generate("warehouse"));
//
//        Order result = orderService.findById(id);
//        return CommResult.success(result);
//    }

    /**
     * 确认完成
     *
     * @param id
     * @return
     */
    @ApiOperation("确认完成")
    @PostMapping("/complete")
    public CommResult<Order> complete(Long id) {

        Order order = orderService.selectByPrimaryKey(id);

        if (order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_COMPLETE.getId()) ||
                order.getOrderStatus().equals(OrderStatusEnum.ORDER_STATUS_REVIEWED.getId())
                ) {
            return CommResult.error("订单已完成");
        }

        //检查是否退货中
        Map<String,Object> params = new HashMap<>();
        params.put("orderId",id);

        List<Askfor> askforList = askforService.selectList(params);
        for (Askfor rn:askforList) {
            if (!rn.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_COMPLETE.getId())
                    &&
                    !rn.getStatus().equals(AskforStatusEnum.ASKFOR_STATUS_CANCLEED.getId())
                    ) {
                return CommResult.error("退货未完成");
            }
        }

        //检查是否退货中
//        if (order.getShippingMethod().equals(2)) {
//            params.clear();
//            params.put("orderId", id);
//            List<Shipping> shippingList = shippingService.selectList(params);
//            for (Shipping rn : shippingList) {
//                if (rn.getShippingStatus().equals(ShippingStatusEnum.SHIPPING_STATUS_SEND.getId())
//                        ||
//                        rn.getShippingStatus().equals(ShippingStatusEnum.SHIPPING_STATUS_DISPATCH.getId())
//                        ||
//                        rn.getShippingStatus().equals(ShippingStatusEnum.SHIPPING_STATUS_UNCONFIRM.getId())
//                        ) {
//                    return CommResult.error("订单配送中");
//                }
//            }
//
//        }

//        params.clear();
//        params.put("orderId",id);
//        params.put("status",0);
//        Integer w = orderPlanService.selectRowCount(params);
//        if (w>0) {
//            return CommResult.error("配送没有完成");
//        }

        int affectCount = orderService.received(id,false);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Order result = orderService.findById(id);
        return CommResult.success(result);

    }


    /**
     * 关闭订单
     *
     * @param id
     * @return
     */
    @ApiOperation("关闭订单")
    @PostMapping("/cancel/{id}")
    public CommResult<Order> cancel(@PathVariable Long id) {

        try {

            List<Refunds> refundsList = orderService.cancel(id, sysSequenceService.generate("refunds"),"admin");

            for (Refunds refunds:refundsList) {
                //TODO发送退款通知
                Attach attachQueue = new Attach();
                attachQueue.setCode("0000");
                attachQueue.setId(String.valueOf(refunds.getId()));
                attachQueue.setQueue("queue.refunds.submit");
                Message message = MessageBuilder
                        .withBody(JSON.toJSONString(attachQueue).getBytes())
                        .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                        .build();
                CorrelationData correlationData = new CorrelationData();
                correlationData.setId(UUID.randomUUID().toString());
                logger.info("发送 MQ");
                rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);
            }

        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }
        Order result = orderService.findById(id);
        return CommResult.success(result);
    }


    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("订单打印")
    @GetMapping("/print/{id}")
    public void print(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("订单不存在");
        }

        Map<String, Object> param = new HashMap<String, Object>();
        param = HttpUtils.requestParam(request);
        Enterprise enterprise = enterpriseService.getCurrent();
        if (null == enterprise) {
            throw new CustomException("没有开通企业");
        }
        param.put("enterpriseId",enterprise.getId());
        logger.info("打印报表查询参数：{}", param.toString());

        String fileName = enterprise.getMchId()+"_"+order.getSn() + ".jasper";
        //fileName就是sys_report表的id
        SysReport sysReport = sysReportService.selectByPrimaryKey(fileName);

        String filePath = "";
        if (System.getProperty("os.name").contains("Windows")) {
            filePath = windowsFilePath;
        } else if (System.getProperty("os.name").contains("Linux")) {
            filePath = linuxFilePath;
        }
        //检查服务器上是否存在模板
        File file = new File(filePath + File.separator + fileName);
        if (!file.exists()){
            try {
                //不存在，从服务器上下载
                String url = sysReport == null?"":sysReport.getTemplate();
                sysReportService.fileDownLoad(response, url, filePath, fileName);
            } catch (Exception e){
                logger.info("打印模板下载失败");
                throw new CustomException("打印模板下载失败");
            }
        }

        param.put("COMPANY",enterprise.getName());
        param.put("REPORT_NAME", "销售单");
        String reportName = "orderPrint";
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT j.*,m.name as member_name,o.name as office_name,e.name as operate_name from (");
        sql.append(" SELECT ");
        sql.append("     a.id,a.member_id,a.office_id,a.operator,a.sn order_sn,a.amount_payable,b.sn,a.consignee,a.phone,a.area_name,a.address,a.order_date,b.price,b.quantity,b.price*b.quantity as amount,b.discount,a.memo,b.name,b.unit,b.spec ");
        sql.append(" FROM wx_order a,wx_order_item b");
        sql.append(" WHERE a.id=b.order_id and a.id = "+id+") j ");
        sql.append(" LEFT OUTER JOIN wx_member m on j.member_id = m.id ");
        sql.append(" LEFT OUTER JOIN sys_office o on j.office_id = o.id ");
        sql.append(" LEFT OUTER JOIN sys_employee e on j.operator = e.id ");

        File file2 = new File(filePath + File.separator + fileName);
        if (!file2.exists()) {
            //下载之后还不存在，就使用classpath路径的模板
            sysReportService.ReportToPdfBySql(reportName, param, sql.toString(), response);
        } else {
            sysReportService.commReportToPdf(filePath, fileName, param, sql.toString(), response);
        }

    }

    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("导出订单")
    @GetMapping("/export/{id}")
    public void export(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{

        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("订单不存在");
        }

        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        param.put("COMPANY",enterprise.getName());
        param.put("REPORT_NAME", "销售单");
        String reportName = "orderPrint";
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT j.*,m.name as member_name,o.name as office_name,e.name as operate_name from (");
        sql.append(" SELECT ");
        sql.append("     a.id,a.member_id,a.office_id,a.operator,a.sn order_sn,b.sn,a.amount_payable,a.consignee,a.phone,a.area_name,a.address,a.order_date,b.price,b.quantity,b.price*b.quantity as amount,b.discount,a.memo,b.name,b.unit,b.spec ");
        sql.append(" FROM wx_order a,wx_order_item b");
        sql.append(" WHERE a.id=b.order_id and a.id = "+id+") j ");
        sql.append(" LEFT OUTER JOIN wx_member m on j.member_id = m.id ");
        sql.append(" LEFT OUTER JOIN sys_office o on j.office_id = o.id ");
        sql.append(" LEFT OUTER JOIN sys_employee e on j.operator = e.id ");

        param.put("REPORT_NAME", "销售单");

        sysReportService.ReportToExcelBySql(reportName, param, sql.toString(), response);

    }

    /**
     * 会员推广的订单
     *
     * @return
     */
    @ApiOperation("会员推广的订单")
    @GetMapping("/orderList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "会员ID", dataType = "Long", paramType = "query")
    })
    public CommResult<Order> orderList(Long memberId,Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);

        Member member = memberService.selectByPrimaryKey(memberId);
        params.put("promoterId1", member.getId());

        Page<Object> startPage = PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<Order> list = orderService.selectList(params);
        PageResult<Order> pageResult = new PageResult<Order>(list, startPage.getTotal(), pageable);
        return CommResult.success(pageResult);
    }


}
